﻿using System.Globalization;

namespace System
{
    public static partial class Extention
    {
        public static string Format(this DateTime dateTime,string format = null) {
            if(format.IsNull())
                format = "yyyy-MM-dd HH:mm:ss";

            return dateTime.ToString(format);
        }
        ///   <summary> 
        ///  获取某一日期是该年中的第几周
        ///   </summary> 
        ///   <param name="dateTime"> 日期 </param> 
        ///   <returns> 该日期在该年中的周数 </returns> 
        public static int GetWeekOfYear(this DateTime dateTime)
        {
            GregorianCalendar gc = new GregorianCalendar();
            return gc.GetWeekOfYear(dateTime, CalendarWeekRule.FirstDay, DayOfWeek.Monday);
        }
        /// <summary>
        /// 获取周几
        /// </summary>
        /// <param name="datetime"></param>
        /// <returns></returns>
        public static string GetWeek(this DateTime datetime) {
            var dayOfWeek = datetime.DayOfWeek.ToInt();
            string week;
            switch(dayOfWeek) {
                case 0:
                    week = "星期日";
                    break;
                case 1:
                    week = "星期一";
                    break;
                case 2:
                    week = "星期二";
                    break;
                case 3:
                    week = "星期三";
                    break;
                case 4:
                    week = "星期四";
                    break;
                case 5:
                    week = "星期五";
                    break;
                default:
                    week = "星期六";
                    break;
            }
            return week;
        }
        /// <summary>
        /// 获取Js格式的timestamp
        /// </summary>
        /// <param name="dateTime">日期</param>
        /// <returns></returns>
        public static long ToJsTimestamp(this DateTime dateTime)
        {
            var startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1, 0, 0, 0, 0));
            long result = (dateTime.Ticks - startTime.Ticks) / 10000;   //除10000调整为13位
            return result;
        }

        /// <summary>
        /// 获取js中的getTime()
        /// </summary>
        /// <param name="dt">日期</param>
        /// <returns></returns>
        public static Int64 JsGetTime(this DateTime dt)
        {
            Int64 retval = 0;
            var st = new DateTime(1970, 1, 1);
            TimeSpan t = (dt.ToUniversalTime() - st);
            retval = (Int64)(t.TotalMilliseconds + 0.5);
            return retval;
        }

        /// <summary>
        /// 返回默认时间1970-01-01
        /// </summary>
        /// <param name="dt">时间日期</param>
        /// <returns></returns>
        public static DateTime Default(this DateTime dt)
        {
            return DateTime.Parse("1970-01-01");
        }

        /// <summary>
        /// 月 第一天
        /// </summary>
        /// <param name="Year"></param>
        /// <param name="Month"></param>
        /// <returns></returns>
        public static DateTime GetFirstDayOfMonth(int Year, int Month)
        {
            //你见过不是从1号开始的月份么？没有 
            //那么，直接返回给调用者吧！ 
            //良好的一个编程习惯就是你的代码让人家看了简单易懂           
            return Convert.ToDateTime(Year.ToString() + "-" + Month.ToString() + "-1");
        }
        /// <summary>
        /// 月 最后一天
        /// </summary>
        /// <param name="Year"></param>
        /// <param name="Month"></param>
        /// <returns></returns>
        public static DateTime GetLastDayOfMonth(int Year, int Month)
        {
            //这里的关键就是 DateTime.DaysInMonth 获得一个月中的天数          
            int Days = DateTime.DaysInMonth(Year, Month);
            return Convert.ToDateTime(Year.ToString() + "-" + Month.ToString() + "-" + Days.ToString());
        }
        /// <summary>
        /// yyyy-MM-dd
        /// </summary>
        public static string ToString5(this DateTime dt)
        {
            return (dt == new DateTime() ? string.Empty : dt.ToString("yyyy-MM-dd"));
        }
        /// <summary>
        /// yyyy-MM-dd HH:mm:ss
        /// </summary>
        public static string ToString6(this DateTime dt)
        {
            return (dt == new DateTime() ? string.Empty : dt.ToString("yyyy-MM-dd HH:mm:ss"));
        }
        /// <summary>
        /// yyyyMMddHHmmssfff
        /// </summary>
        public static string ToString7(this DateTime dt)
        {
            return (dt == new DateTime() ? string.Empty : dt.ToString("yyyyMMddHHmmssfff"));
        }
        /// <summary>
        /// 判断时间是否在区间内
        /// </summary>
        /// <param name="this"></param>
        /// <param name="start">开始</param>
        /// <param name="end">结束</param>
        /// <param name="mode">模式</param>
        /// <returns></returns>
        public static bool In(this in DateTime @this,DateTime start,DateTime end,RangeMode mode = RangeMode.Close) {
            return mode switch {
                RangeMode.Open => start<@this&&end>@this,
                RangeMode.Close => start<=@this&&end>=@this,
                RangeMode.OpenClose => start<@this&&end>=@this,
                RangeMode.CloseOpen => start<=@this&&end>@this,
                _ => throw new ArgumentOutOfRangeException(nameof(mode),mode,null)
            };
        }
        /// <summary>判断当前年份是否是闰年，私有函数</summary>
        /// <param name="iYear">年份</param>
        /// <returns>是闰年：True ，不是闰年：False</returns>
        public static bool IsRuYear(this int iYear) {
            //形式参数为年份
            //例如：2003
            var n = iYear;
            return n%400==0||n%4==0&&n%100!=0;
        }
        /// <summary>
        /// 获得一段时间内有多少小时
        /// </summary>
        /// <param name="dtStar">起始时间</param>
        /// <param name="dtEnd">终止时间</param>
        /// <returns>小时差</returns>
        public static string GetTimeDelay(this in DateTime dtStar,DateTime dtEnd) {
            long lTicks = (dtEnd.Ticks-dtStar.Ticks)/10000000;
            string sTemp = (lTicks/3600).ToString().PadLeft(2,'0')+":";
            sTemp+=(lTicks%3600/60).ToString().PadLeft(2,'0')+":";
            sTemp+=(lTicks%3600%60).ToString().PadLeft(2,'0');
            return sTemp;
        }
        /// <summary>
        /// 计算2个时间差
        /// </summary>
        /// <param name="beginTime">开始时间</param>
        /// <param name="endTime">结束时间</param>
        /// <returns>时间差</returns>
        public static string GetDiffTime(this in DateTime beginTime,in DateTime endTime) {
            string strResout = string.Empty;

            //获得2时间的时间间隔秒计算
            TimeSpan span = endTime.Subtract(beginTime);
            int sec = Convert.ToInt32(span.TotalSeconds);
            int minutes = 1*60;
            int hours = minutes*60;
            int day = hours*24;
            int month = day*30;
            int year = month*12;

            //提醒时间,到了返回1,否则返回0
            if(sec>year) {
                strResout+=sec/year+"年";
                sec%=year; //剩余
            }

            if(sec>month) {
                strResout+=sec/month+"月";
                sec%=month;
            }

            if(sec>day) {
                strResout+=sec/day+"天";
                sec%=day;
            }

            if(sec>hours) {
                strResout+=sec/hours+"小时";
                sec%=hours;
            }

            if(sec>minutes) {
                strResout+=sec/minutes+"分";
                sec%=minutes;
            }

            strResout+=sec+"秒";
            return strResout;
        }
    }
    /// <summary>
    /// 区间模式
    /// </summary>
    public enum RangeMode {
        /// <summary>
        /// 开区间
        /// </summary>
        Open,

        /// <summary>
        /// 闭区间
        /// </summary>
        Close,

        /// <summary>
        /// 左开右闭区间
        /// </summary>
        OpenClose,

        /// <summary>
        /// 左闭右开区间
        /// </summary>
        CloseOpen
    }
}
